package com.gxa.community.customer.service.order.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxa.community.core.pojo.bo.order.OrderAndGoodsInfo;
import com.gxa.community.core.pojo.domain.OrderInfo;
import com.gxa.community.core.pojo.vo.order.GoodsInfoVo;
import com.gxa.community.core.pojo.vo.order.OrderInfoVo;
import com.gxa.community.core.pojo.vo.order.TrhOrderVO;
import com.gxa.community.core.pojo.vo.order.UserAndAgentAndGoodsInfoVO;
import com.gxa.community.core.utils.R;
import com.gxa.community.customer.service.order.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    public static final String TRH_ORDER_CACHE = "trhOrder:";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public String preCreateOrder(Integer userId) {
        //下单前获取用户信息（包括优惠券 提货人  自提点）
        //TODO 发起远程通信获取
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        String url="http://kinggo.icu:8080/order/queryuserinfodto?userId={userId}";
        String forObject = restTemplate.getForObject(url, String.class, map);
        return forObject;
    }

    @Override
    public String createOrder(UserAndAgentAndGoodsInfoVO userAndAgentAndGoodsInfoVO) throws JsonProcessingException {
        TrhOrderVO trhOrderVO = new TrhOrderVO();//封装订单生成后 传回前端的数据  同时也要存入缓存（用于更改用户购物车信息）
        //先将商品id和商品数量存进去
        Map<Integer, Integer> map = trhOrderVO.getMap();
        List<GoodsInfoVo> goodsInfoVoList = userAndAgentAndGoodsInfoVO.getGoodsInfoVoList();
        for (GoodsInfoVo goodsInfoVo : goodsInfoVoList) {
            map.put(goodsInfoVo.getId(),goodsInfoVo.getGoodsNum());
        }
        //需要对前端传入的参数在封装  需要团长id  当前用户id  收货人名称  收货人手机号  使用的消费券id ，
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        orderInfoVo.setAgentId(userAndAgentAndGoodsInfoVO.getAgentId())
                .setBuyerId(userAndAgentAndGoodsInfoVO.getUserId())
                .setCouponId(userAndAgentAndGoodsInfoVO.getCouponId())
                .setReceiverName(userAndAgentAndGoodsInfoVO.getReceiveName())
                .setReceiverPhone(userAndAgentAndGoodsInfoVO.getReceivePhone())
                .setType(userAndAgentAndGoodsInfoVO.getType());
        OrderAndGoodsInfo orderAndGoodsInfo = new OrderAndGoodsInfo();
        orderAndGoodsInfo.setOrderInfo(orderInfoVo)
                .setGoodsInfo(userAndAgentAndGoodsInfoVO.getGoodsInfoVoList());
        //TODO 发起远程通信生成订单
        String url = "http://kinggo.icu:8080/order/createOrder";
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        MultiValueMap<String, OrderAndGoodsInfo> postParameters = new LinkedMultiValueMap<>();
        postParameters.add("info",orderAndGoodsInfo);
        HttpEntity<MultiValueMap<String,OrderAndGoodsInfo>> httpEntity = new HttpEntity<>(postParameters,httpHeaders);
        R r = restTemplate.postForObject(url, httpEntity, R.class);
        OrderInfo oi = (OrderInfo) r.get("data");
        trhOrderVO.setOrderInfo(oi);
        r.remove("data");
        r.put("data",trhOrderVO);
        ObjectMapper objectMapper = new ObjectMapper();
        String s = objectMapper.writeValueAsString(r);
        //将生成的待付款订单存入redis,有效时间30分钟
        redisTemplate.opsForValue().set(TRH_ORDER_CACHE+oi.getNos(),s,30, TimeUnit.MINUTES);
        return s;
    }
}
